<!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>CRAP&#8482; Monitor</title>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="css/monitor.css">
    <link href="css/bootstrap-responsive.min.css" rel="stylesheet">    
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <script type="text/javascript" language="javascript" src="js/jquery-1.8.3.min.js"></script>
    <script type="text/javascript" language="javascript" src="js/bootstrap.min.js"></script>
    <script type="text/javascript" language="javascript" src="js/jquery.dataTables-1.9.4.min.js"></script>
    <script type="text/javascript" language="javascript" src="js/datatables-bootstrap-pagation.js"></script>
    <script type="text/javascript" language="javascript" src="js/datatables-reload-ajax.js"></script>
    <script type="text/javascript" charset="utf-8">
      // overwrites for bootstrap
      $.extend( $.fn.dataTableExt.oStdClasses, {
        "sWrapper": "dataTables_wrapper form-inline"
      } );

      // WS locations to get the data
      var allContentUrl = "dataset/process"; 
      var runningContentUrl = "dataset/process/running"; 
      var queueContentUrl = "dataset/process/queued"; 
      var detailUrl = "dataset/process/detail/"; 
      
      var oTable; // The main data table 
      
      // utility to trigger live view class
      var click = function() {
        // live view is monitored on the polling, the second is bootstrap styling only
        $(this).toggleClass('row_liveview').toggleClass('success');          
      }
      
      // decorates rows with missing pieces
      var decorate = function(nRow, aData) {
        $('td:eq(0)', nRow).addClass("url");
        $('td:eq(0)', nRow).css("width","80px");

        var $log = $("<a href='#'>Logs</a>").bind('click', function() {
          // TODO: replace with a proper link
          alert(aData.datasetKey);
          return false;});
          
        var $details = $("<a href='#'>Details</a>").bind('click', function() {
          if ( oTable.fnIsOpen(nRow) ) {
            oTable.fnClose( nRow );
          } else {
          	oTable.fnOpen( nRow, "TODO: Insert the details", "info_row" );
          }          
          return false;
        });
          
        $('td:eq(10)', nRow).html("");  
        $('td:eq(10)', nRow).append($log).append(" | ").append($details);
      }    
    
      $(document).ready(function() {    
        /*
         * Set up the data table
         */
				oTable = $('#datasetCrawls')
				  .dataTable( {
						"sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
						"sAjaxSource": allContentUrl,
						"sAjaxDataProp": "",  // There is no field name - e.g. {[i1,i2]} not {"data":[i1,i2]}
						"aoColumns": [
							{ "mData": "address", sDefaultContent: "http://mockprovider1.gbif.org/tapir/admin.php" },  // defaults to be fail safe when omitted in JSON
							{ "mData": "datasetKey", sDefaultContent: "" },
							{ "mData": "status", sDefaultContent: "" },
							{ "mData": "errors", sDefaultContent: "0" }, 
							{ "mData": "pagesCrawled", sDefaultContent: "0" }, 
							{ "mData": "pagesFragmented", sDefaultContent: "0" }, 
							{ "mData": "fragmentsGenerared", sDefaultContent: "0" }, 
							{ "mData": "fragmentsPersisted", sDefaultContent: "0" },
							{ "mData": "recordsCreated", sDefaultContent: "0" },
							{ "mData": "recordsInterpreted", sDefaultContent: "0" },
							{ sDefaultContent: " ", 'bSortable': false }, // crawl logs
						], // The data definition
						"fnRowCallback" :  function(nRow, aData, iDisplayIndex) { // inject the missing fields
							decorate(nRow, aData);
							// row click handling by toggling a class, which enables live view
							// we unbind to ensure only 1 event logs
							$(nRow).unbind('click').bind('click', click);
						},
						"bProcessing": true, // Show processing indicator when busy
						"bDeferRender": true, // delay rendering for performance
						"bStateSave" : true, // save current state in cookie to help reload
						"fnInitComplete": function() {  
							// restores saved filters on refresh
							// http://datatables.net/forums/discussion/2864/x
							var oSettings = $('#datasetCrawls').dataTable().fnSettings();
							for ( var i=0 ; i<oSettings.aoPreSearchCols.length ; i++ ) {
								if(oSettings.aoPreSearchCols[i].sSearch.length>0){
									$("tfoot input")[i].value = oSettings.aoPreSearchCols[i].sSearch;
									$("tfoot input")[i].className = "";
								}
							}
							
						}, 
						// There appears a bug that DT is disabling the tabs incorrectly - reenable here
            "fnDrawCallback": function( oSettings ) {
              $('#tabs li').removeClass("disabled");  
            },						
						"oLanguage" : { // custom labels
						"sSearch": "Quick search: ", 
					},"sPaginationType": "bootstrap"});
        
        /*
         * Support functions to provide a little bit of 'user friendlyness' to the textboxes in
         * the footer
         */
        var asInitVals = new Array();
        $("tfoot input").each( function (i) {
          asInitVals[i] = this.value;
        });
        $("tfoot input").focus( function () {
          if ( this.className == "search_init" ) {
          this.className = "";
          this.value = "";
          }
        });
        $("tfoot input").blur( function (i) {
          if ( this.value == "" ) {
          this.className = "search_init";
          this.value = asInitVals[$("tfoot input").index(this)];
          }
        });
        $("tfoot input").keyup( function () {
          /* Filter on the column (the index) of this element */
          oTable.fnFilter( this.value, $("tfoot input").index(this) );
        }); 
        
        /*
         * Tab interceptor to set url of data based on the tab
         */ 
        $("#allTab").click(function() {
          console.log("Switching to all: " + allContentUrl);
          oTable.fnReloadAjax(allContentUrl);
        });
        $("#runningTab").click(function() {
          console.log("Switching to running: " + runningContentUrl);
          oTable.fnReloadAjax(runningContentUrl);
        });
        $("#queueTab").click(function() {
          console.log("Switching to queued: " + queueContentUrl);
          oTable.fnReloadAjax(queueContentUrl);
        });
        $(function () {
			    $('#tabs a:first').tab('show');
			  });
        
        
        /*
         * Live view polling
         */
        function liveView() {
          console.log("Live viewing " +oTable.$('tr.row_liveview').length + " records");
          $.each(oTable.$('tr.row_liveview'), function(index, nRow) {
	          var aData = oTable.fnGetData(nRow);
            $.ajax({
              url: detailUrl + aData.datasetKey,
            }).done(function ( data ) {
              oTable.fnUpdate(data, nRow, undefined, true, true); // don't repaint the table
              decorate(nRow, aData);
            });            
          });        
          setTimeout(function() {
        	  liveView();
          }, 2000); // liveview update period msecs
        }
        
        // start the live view polling
        liveView();
      });
    </script>
  </head>
  <body>
    <!-- Page layout is using bootstrap -->
    <div class="container">
      <div>
        <h3>CRawling And Processing Monitor&#8482; <small> ...filter, sort, click for <em>live view</em></small></h3>
      </div>      
      <ul id="tabs" class="nav nav-tabs">
        <li><a href="#data" data-toggle="tab" id="allTab">Everything</a></li>
        <li><a href="#data" data-toggle="tab" id="runningTab">Running now</a></li>
        <li><a href="#data" data-toggle="tab" id="queueTab">Queued</a></li>
        <li><a href="#health" data-toggle="tab">Health</a></li>
      </ul>
      <div class="tab-content">
        <div class="tab-pane active" id="data">  
					<div id="tabTable">
						<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered table-condensed" id="datasetCrawls">
							<thead>
								<tr>
								<th>URL</th>
								<th>Dataset</th>
								<th title="Crawler status">Status</th>
								<th title="Crawler errors">Errors</th>
								<th title="Pages crawled">PC</th>
								<th title="Pages fragmented">PF</th>
								<th title="Fragments generated">FG</th>
								<th title="Fragments persisted">FP</th>
								<th title="Records created">RU</th>
								<th title="Records interpreted">RI</th>
								<th title="Miscellaneous" style="width:150px"></th>
								</tr>
							</thead>
							<tbody/>
							<tfoot>
								<tr>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:80%"/></th>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:80%"/></th>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:80%"/></th>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:80%"/></th>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:80%"/></th>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:80%"/></th>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:80%"/></th>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:80%"/></th>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:80%"/></th>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:80%"/></th>
								<th><input type="text" name="search_ds" value="..." class="search_init" style="width:0px;visibility:hidden"/></th>
								</tr>
							</tfoot>     
						</table> 
						<p/>
					</div>			
        </div>
			  <div class="tab-pane" id="health">
	        <div class="alert alert-error">
  	        <h4>Error!</h4>
    	      HBase is not responding
      	  </div>
	        <div class="alert alert-warning">
  	        <h4>Warning!</h4>
    	      Unable to test RabbitMQ
      	  </div>
	        <div class="alert alert-warning">
  	        <h4>Warning!</h4>
    	      Unable to test log server
      	  </div>
	        <div class="alert alert-success">Web services are operational</div>
  	      <div class="alert alert-success">ZooKeeper is operational</div>      
    	  </div>        
      </div>
  </body>
</html>